Imports System
Imports System.Drawing
Imports System.Collections.Generic
Imports System.Text
Imports System.Runtime.InteropServices
Imports Microsoft.Win32
Imports System.ComponentModel
Imports System.IO
Imports System.Windows.Media.Imaging
Namespace C4F.DevKit.PictureAcquisition
    ''' <summary>
    ''' Contains methods for management of picture acquisition.
    ''' </summary>
    <ToolboxItem(True), ToolboxBitmap(GetType(PictureAcquisitionManager))> _
    Public Class PictureAcquisitionManager : Inherits Component
#Region "Private members"

        Private photoAcquireItem As PictureAcquisitionNative.IPhotoAcquireItem

        ' Create object of IPhotoAcquireSettings.
        Private acquireSetting As PictureAcquisitionNative.IPhotoAcquireSettings

        ' Object for getting selected device information.
        Private selectedDeviceInfo As DeviceInfo

        ' Error code returned from API method call.
        Private errorResult As APIErrors

        ' Used to set and get file name template.
        Private fileNameTemplate As String = ""


        Private Function CallBackMethod() As Boolean
            Return False
        End Function

        ''' <summary>
        ''' Creates temporary files.
        ''' </summary>
        ''' <param name="deviceId">Id of device , of which temporary file to be creted.</param>
        ''' <returns>List of file names.</returns>
        Private Function CreateTemporaryFiles(ByVal deviceId As String) As List(Of String)
            ' Create the PhotoAcquire object.
            Dim photoAcquireObject As PictureAcquisitionNative.PhotoAcquire = Nothing
            Dim photoAcquire As PictureAcquisitionNative.IPhotoAcquire = Nothing

            Dim photoAcquireSource As PictureAcquisitionNative.IPhotoAcquireSource = Nothing
            ' Set to default value.
            errorResult = APIErrors.S_OK

            Dim imageName As List(Of String) = New List(Of String)

            Try
                photoAcquireObject = New PictureAcquisitionNative.PhotoAcquire()
                photoAcquire = CType(photoAcquireObject, PictureAcquisitionNative.IPhotoAcquire)

                errorResult = CType(photoAcquire.CreatePhotoSource(deviceId, photoAcquireSource), APIErrors)

                If (errorResult <> APIErrors.S_OK) Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If

                Dim itemCount As UInteger = 0
                errorResult = CType(photoAcquireSource.InitializeItemList(True, IntPtr.Zero, itemCount), APIErrors)

                If (errorResult <> APIErrors.S_OK) Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If

                Dim index As Integer

                For index = 0 To CType(itemCount - 1, Integer) Step 1

                    Dim comStream As System.Runtime.InteropServices.ComTypes.IStream = Nothing

                    errorResult = CType(photoAcquireSource.GetItemAt(CType(index, UInteger), photoAcquireItem), APIErrors)

                    If (errorResult <> APIErrors.S_OK) Then
                        Throw New PictureAcquisitionException(errorResult.ToString())
                    End If

                    ' Get object of stream.
                    errorResult = CType(photoAcquireItem.GetStream(comStream), APIErrors)

                    If (errorResult <> APIErrors.S_OK) Then
                        Throw New PictureAcquisitionException(errorResult.ToString())
                    End If

                    Dim comStreamInfo As System.Runtime.InteropServices.ComTypes.STATSTG = New System.Runtime.InteropServices.ComTypes.STATSTG()

                    ' Get information about retrieved stream object.
                    comStream.Stat(comStreamInfo, 0)

                    Dim bytes(CType(comStreamInfo.cbSize, Integer)) As Byte

                    ' Read all bytes of stream in byte buffer.
                    comStream.Read(bytes, CType(comStreamInfo.cbSize, Integer), IntPtr.Zero)

                    imageName.Add(comStreamInfo.pwcsName)

                    If (Not (Directory.Exists(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + PictureAcquisitionResource.TempLocation))) Then
                        Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + PictureAcquisitionResource.TempLocation)
                    End If
                    ' Create a new file steram (file) at temporary location.
                    Dim FileStream As FileStream = New FileStream(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + PictureAcquisitionResource.TempLocation + comStreamInfo.pwcsName, FileMode.OpenOrCreate)

                    ' Write bytes of buffer in this new file.
                    FileStream.Write(bytes, 0, CType(comStreamInfo.cbSize, Integer))

                    FileStream.Close()

                    FileStream.Dispose()

                    FileStream = Nothing

                    If (comStream IsNot Nothing) Then
                        Marshal.ReleaseComObject(comStream)
                    End If
                Next

            Catch exception As Exception
                If (exception.Message = PictureAcquisitionResource.ResultFileNotFound) Then
                    Throw New ArgumentException(PictureAcquisitionResource.InvalidDeviceId)
                End If
                If (exception.Message = PictureAcquisitionResource.InvalidArg) Then
                    Throw New ArgumentException(PictureAcquisitionResource.InvalidDeviceId)
                Else
                    Throw New PictureAcquisitionException(exception.Message)
                End If
            Finally

                If (photoAcquireObject IsNot Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireObject)
                End If

                If (photoAcquire IsNot Nothing) Then
                    Marshal.ReleaseComObject(photoAcquire)
                End If

                If (photoAcquireSource IsNot Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireSource)
                End If

                If (photoAcquireItem IsNot Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireItem)
                End If
            End Try
            Return imageName
        End Function

#End Region
#Region "Constructor"

        ''' <summary>
        ''' Creates an instance of PhotoAcquisitionManager class object.
        ''' </summary>
        Public Sub New()
        End Sub

#End Region
#Region "Public methods"
#Region "AcquireItems"
        ''' <summary>
        ''' Acquires picture and video items from specified device.
        ''' </summary>
        ''' <param name="deviceId">Id of device from which to acquire items.</param>
        ''' <param name="showProgressDialog">Specifies whether progress dialog to be shown or not.</param>
        ''' <returns>List of item names, actually acquired.</returns>
        ''' <exception cref="ArgumentNullException">
        ''' The required parameter is null or empty.
        ''' </exception>
        ''' <exception cref="ArgumentException">
        ''' The specified parameter is not valid.
        ''' </exception>
        ''' <exception cref="PictureAcquisitionException">
        ''' Call to native API has raised an error.
        ''' </exception>
        Public Function AcquireItems(ByVal deviceId As String, ByVal showProgressDialog As Boolean) As List(Of String)

            ' Check for null arguments.
            If String.IsNullOrEmpty(deviceId) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterDeviceId)
            End If

            ' Set to default value.
            errorResult = APIErrors.S_OK

            ' Create the PhotoAcquire object.
            Dim photoAcquireObject As PictureAcquisitionNative.PhotoAcquire = Nothing
            Dim photoAcquire As PictureAcquisitionNative.IPhotoAcquire = Nothing

            Dim photoAcquireSource As PictureAcquisitionNative.IPhotoAcquireSource = Nothing

            Dim itemsImportedList As List(Of String) = New List(Of String)()
            Try

                photoAcquireObject = New PictureAcquisitionNative.PhotoAcquire()
                photoAcquire = CType(photoAcquireObject, PictureAcquisitionNative.IPhotoAcquire)

                ' Create photosource for acquiring items from.
                errorResult = CType(photoAcquire.CreatePhotoSource(deviceId, photoAcquireSource), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                ' Create instance of IPhotoAcquireSettings.
                errorResult = CType(photoAcquireSource.GetPhotoAcquireSettings(acquireSetting), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If

                Dim progressBar As Int32

                If (showProgressDialog = True) Then
                    progressBar = 1
                Else
                    progressBar = 0
                End If

                ' Acquire items from specified device to the default location.
                errorResult = CType(photoAcquire.Acquire(photoAcquireSource, progressBar, IntPtr.Zero, "Test Application", Nothing), APIErrors)
                If errorResult <> APIErrors.S_OK AndAlso errorResult <> APIErrors.E_ABORT Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                ' Create object of IEnumString.
                Dim enumstring As PictureAcquisitionNative.IEnumString = Nothing
                ' Get enumeration of items actually acquired from specified device.
                errorResult = CType(photoAcquire.EnumResults(enumstring), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                ' Make list of items acquired.
                Dim index As Integer = 0
                While True
                    Dim name As String = String.Empty
                    Dim fetched As UInteger
                    ' Retrieve next item from enumeration.
                    errorResult = CType(enumstring.RemoteNext(1, name, fetched), APIErrors)
                    If errorResult = APIErrors.S_OK Then
                        itemsImportedList.Add(name)
                    Else
                        Exit While
                    End If
                    index += 1
                End While
            Catch exception As Exception
                If exception.Message = PictureAcquisitionResource.ResultFileNotFound Then
                    Throw New ArgumentException(PictureAcquisitionResource.InvalidDeviceId)
                End If
                If exception.Message = PictureAcquisitionResource.InvalidArg Then
                    Throw New ArgumentException(PictureAcquisitionResource.InvalidDeviceId)
                Else
                    Throw New PictureAcquisitionException(exception.Message)
                End If

            Finally
                If (Not photoAcquireObject Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireObject)
                End If

                If (Not photoAcquire Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquire)
                End If

                If (Not photoAcquireSource Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireSource)
                End If
            End Try

            Return itemsImportedList

        End Function

        ''' <summary>
        ''' Acquires picture and video items from specified device.
        ''' </summary>
        ''' <param name="deviceId">Id of device from which to acquire items.</param>
        ''' <param name="showProgressDialog">Specifies progress dialog is to be shown or not.</param>
        ''' <param name="targetLocation">Location for saving pictures of specified device.</param>
        ''' <returns>List of item names, actually acquired.</returns>
        ''' <exception cref="ArgumentNullException">
        ''' The required parameter is null or empty.
        ''' </exception>
        ''' <exception cref="ArgumentException">
        ''' The specified parameter is not valid.
        ''' </exception>
        ''' <exception cref="PictureAcquisitionException">
        ''' Call to native API has raised an error.
        ''' </exception>
        Public Function AcquireItems(ByVal deviceId As String, ByVal showProgressDialog As Boolean, ByVal targetLocation As String) As List(Of String)

            If (String.IsNullOrEmpty(targetLocation)) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterLocation)
            End If

            If (Not Directory.Exists(targetLocation)) Then
                Directory.CreateDirectory(targetLocation)
            End If

            ' Check for null arguments.
            If String.IsNullOrEmpty(deviceId) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterDeviceId)
            End If

            ' Check for null or empty string
            If Not String.IsNullOrEmpty(targetLocation) Then
                ' Check for maximum length of fileNameTemplate.
                If targetLocation.Length > 207 Then
                    Throw New ArgumentException(PictureAcquisitionResource.TemplateMaxLength)
                End If
            End If

            targetLocation += "\$(OriginalFileName).$(OriginalExtension)"

            ' Create the PhotoAcquire object.
            Dim photoAcquireObject As PictureAcquisitionNative.PhotoAcquire = Nothing
            Dim photoAcquire As PictureAcquisitionNative.IPhotoAcquire = Nothing

            Dim photoAcquireSource As PictureAcquisitionNative.IPhotoAcquireSource = Nothing


            ' Set to default value.
            errorResult = APIErrors.S_OK
            Dim itemsImportedList As List(Of String) = New List(Of String)()
            Try

                photoAcquireObject = New PictureAcquisitionNative.PhotoAcquire()
                photoAcquire = CType(photoAcquireObject, PictureAcquisitionNative.IPhotoAcquire)

                ' Create photosource for acquiring items from.
                errorResult = CType(photoAcquire.CreatePhotoSource(deviceId, photoAcquireSource), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                ' Create instance of IPhotoAcquireSettings.
                errorResult = CType(photoAcquireSource.GetPhotoAcquireSettings(acquireSetting), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                If Not (String.IsNullOrEmpty(targetLocation)) Then
                    ' Set file name template.
                    errorResult = CType(acquireSetting.SetOutputFilenameTemplate(targetLocation), APIErrors)
                    If errorResult <> APIErrors.S_OK Then
                        Throw New PictureAcquisitionException(errorResult.ToString())
                    End If
                End If

                Dim progressBar As Int32

                If (showProgressDialog = True) Then
                    progressBar = 1
                Else
                    progressBar = 0
                End If

                ' Acquire items from specified device to the default location.
                errorResult = CType(photoAcquire.Acquire(photoAcquireSource, progressBar, IntPtr.Zero, "Test Application", Nothing), APIErrors)
                If errorResult <> APIErrors.S_OK AndAlso errorResult <> APIErrors.E_ABORT Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                ' Create object of IEnumString.
                Dim enumstring As PictureAcquisitionNative.IEnumString = Nothing
                ' Get enumeration of items actually acquired from specified device.
                errorResult = CType(photoAcquire.EnumResults(enumstring), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                ' Make list of items acquired.
                Dim index As Integer = 0
                While True
                    Dim name As String = String.Empty
                    Dim fetched As UInteger
                    ' Retrieve next item from enumeration.
                    errorResult = CType(enumstring.RemoteNext(1, name, fetched), APIErrors)
                    If errorResult = APIErrors.S_OK Then
                        itemsImportedList.Add(name)
                    Else
                        Exit While
                    End If
                    index += 1
                End While
            Catch exception As Exception
                If exception.Message = PictureAcquisitionResource.ResultFileNotFound Then
                    Throw New ArgumentException(PictureAcquisitionResource.InvalidDeviceId)
                End If
                If exception.Message = PictureAcquisitionResource.InvalidArg Then
                    Throw New ArgumentException(PictureAcquisitionResource.InvalidDeviceId)
                Else
                    Throw New PictureAcquisitionException(exception.Message)
                End If

            Finally
                If (Not photoAcquireObject Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireObject)
                End If

                If (Not photoAcquire Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquire)
                End If

                If (Not photoAcquireSource Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireSource)
                End If
            End Try

            Return itemsImportedList

        End Function

        ''' <summary>
        ''' Acquires specified picture and video items from specified device at specified location.
        ''' </summary>
        ''' <param name="deviceId">Id of device from which to acquire items.</param>
        ''' <param name="itemsToAcquire">List of item from device to acquire.</param>
        ''' <param name="targetLocation">Target location , where items of device saved.</param>
        ''' <returns>List of item names, actually acquired.</returns>
        ''' <exception cref="ArgumentNullException">
        ''' The required parameter is null or empty.
        ''' </exception>
        ''' <exception cref="PictureAcquisitionException">
        ''' Call to native API has raised an error.
        ''' </exception>
        Public Function AcquireItems(ByVal deviceId As String, ByVal itemsToAcquire As List(Of String), ByVal targetLocation As String) As List(Of String)

            ' Check for null arguments.
            If (String.IsNullOrEmpty(targetLocation)) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterLocation)
            End If

            If (String.IsNullOrEmpty(deviceId)) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterDeviceId)
            End If

            If (itemsToAcquire Is Nothing) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterDeviceId)
            ElseIf (itemsToAcquire.Count = 0) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterDeviceId)
            End If

            ' Create the PhotoAcquire object.
            Dim photoAcquireObject As PictureAcquisitionNative.PhotoAcquire = Nothing
            Dim photoAcquire As PictureAcquisitionNative.IPhotoAcquire = Nothing

            Dim photoAcquireSource As PictureAcquisitionNative.IPhotoAcquireSource = Nothing

            ' Set to default value.        
            errorResult = APIErrors.S_OK

            Dim itemsImportedList As List(Of String) = New List(Of String)

            Try

                photoAcquireObject = New PictureAcquisitionNative.PhotoAcquire()
                photoAcquire = CType(photoAcquireObject, PictureAcquisitionNative.IPhotoAcquire)

                errorResult = CType(photoAcquire.CreatePhotoSource(deviceId, photoAcquireSource), APIErrors)

                If (errorResult <> APIErrors.S_OK) Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If

                Dim itemCount As UInt32 = 0
                errorResult = CType(photoAcquireSource.InitializeItemList(True, IntPtr.Zero, itemCount), APIErrors)

                If (errorResult <> APIErrors.S_OK) Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                Dim index As Integer
                For index = 0 To CType(itemCount - 1, Integer) Step 1

                    Dim comStream As System.Runtime.InteropServices.ComTypes.IStream = Nothing
                    errorResult = CType(photoAcquireSource.GetItemAt(CType(index, UInt32), photoAcquireItem), APIErrors)

                    If (errorResult <> APIErrors.S_OK) Then
                        Throw New PictureAcquisitionException(errorResult.ToString())
                    End If

                    ' Get object of stream.
                    errorResult = CType(photoAcquireItem.GetStream(comStream), APIErrors)

                    If (errorResult <> APIErrors.S_OK) Then
                        Throw New PictureAcquisitionException(errorResult.ToString())
                    End If

                    Dim itemName As String = Nothing
                    errorResult = CType(photoAcquireItem.GetItemName(itemName), APIErrors)

                    If (errorResult <> APIErrors.S_OK) Then
                        Throw New PictureAcquisitionException(errorResult.ToString())
                    End If

                    If (Not itemsToAcquire.Contains(itemName)) Then
                        Continue For
                    End If


                    Dim comStreamInfo As System.Runtime.InteropServices.ComTypes.STATSTG = New System.Runtime.InteropServices.ComTypes.STATSTG()

                    ' Get information about retrieved stream object.
                    comStream.Stat(comStreamInfo, 0)

                    Dim bytes(CType(comStreamInfo.cbSize, Integer)) As Byte

                    ' Read all bytes of stream in byte buffer.
                    comStream.Read(bytes, CType(comStreamInfo.cbSize, Integer), IntPtr.Zero)

                    If (Not (Directory.Exists(targetLocation))) Then
                        Directory.CreateDirectory(targetLocation)
                    End If

                    ' Create a new file steram (file) at specified target location.
                    Dim FileStream As FileStream = New FileStream(targetLocation + comStreamInfo.pwcsName, FileMode.Create)

                    ' Write bytes of buffer in this new file.
                    FileStream.Write(bytes, 0, CType(comStreamInfo.cbSize, Integer))

                    FileStream.Close()

                    itemsImportedList.Add(comStreamInfo.pwcsName)

                    If (comStream IsNot Nothing) Then
                        Marshal.ReleaseComObject(comStream)
                    End If
                Next

            Catch exception As Exception

                If (exception.Message = PictureAcquisitionResource.ResultFileNotFound) Then
                    Throw New ArgumentException(PictureAcquisitionResource.InvalidDeviceId)
                ElseIf (exception.Message = PictureAcquisitionResource.InvalidArg) Then
                    Throw New ArgumentException(PictureAcquisitionResource.InvalidDeviceId)
                Else
                    Throw New PictureAcquisitionException(exception.Message)
                End If

            Finally

                If (photoAcquireObject IsNot Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireObject)
                End If

                If (photoAcquire IsNot Nothing) Then
                    Marshal.ReleaseComObject(photoAcquire)
                End If
            End Try
            Return itemsImportedList
        End Function
#End Region
#Region "ShowDialog"
        ''' <summary>
        ''' Detects and shows all the devices in the device selection dialog.
        ''' </summary>
        ''' <param name="dialogTitle">Title of device slection dialog.</param>
        ''' <param name="submitButtonText">Text of submit button of device slection dialog.</param>
        ''' <returns>Boolean indicating to do import or not. </returns>
        ''' <exception cref="ArgumentNullException">
        ''' The required parameter is null or empty.
        ''' </exception>
        ''' <exception cref="PictureAcquisitionException">
        ''' Call to native API has raised an error.
        ''' </exception>
        Public Function ShowAllDeviceDialog(ByVal handle As IntPtr, ByVal dialogTitle As String, ByVal submitButtonText As String) As Boolean

            ' Create the device selection dialog object.
            Dim dialogObject As PictureAcquisitionNative.PhotoAcquireDeviceSelectionDialog = Nothing
            Dim selectDevice As PictureAcquisitionNative.IPhotoAcquireDeviceSelectionDialog = Nothing

            ' Check for null arguments.
            If String.IsNullOrEmpty(dialogTitle) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterDialogTitle)
            ElseIf String.IsNullOrEmpty(submitButtonText) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterSubmitButtonText)
            End If
            ' Set to default value.
            errorResult = APIErrors.S_OK
            Dim doImort As Boolean = False
            Dim deviceID As String = String.Empty
            Dim deviceType As UInt32
            Try
                dialogObject = New PictureAcquisitionNative.PhotoAcquireDeviceSelectionDialog()
                selectDevice = CType(dialogObject, PictureAcquisitionNative.IPhotoAcquireDeviceSelectionDialog)

                ' Set text of submit button of device selection dialog.
                errorResult = CType(selectDevice.SetSubmitButtonText(submitButtonText), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                ' Set title text of device selection dialog.
                errorResult = CType(selectDevice.SetTitle(dialogTitle), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                ' Show device selection dialog and detect all devices in the device selection dialog.
                errorResult = CType(selectDevice.DoModal(handle, CType(DeviceFlag.All, UInteger), deviceID, deviceType), APIErrors)
                If errorResult <> APIErrors.S_OK AndAlso errorResult <> APIErrors.E_ABORT Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                Else
                    If errorResult = APIErrors.S_OK Then
                        doImort = True
                        ' Create instance of object, if not already created.
                        If (Me.selectedDeviceInfo Is Nothing) Then
                            Me.selectedDeviceInfo = New DeviceInfo()
                        End If
                        ' Set properties of selectedDeviceInfo object.
                        Me.selectedDeviceInfo.Id = deviceID.ToString()
                        Me.selectedDeviceInfo.Type = CType(deviceType, DeviceType)
                    End If
                End If
            Catch exception As Exception
                Throw New PictureAcquisitionException(exception.Message)
            Finally
                If (Not dialogObject Is Nothing) Then
                    Marshal.ReleaseComObject(dialogObject)
                End If

                If (Not selectDevice Is Nothing) Then
                    Marshal.ReleaseComObject(selectDevice)
                End If
            End Try
            Return doImort
        End Function
        ''' <summary>
        ''' Shows specified devices in the device selection dialog window.
        ''' </summary>
        ''' <param name="devicesTypesToShow">Type of devices to be shown in device slection dialog.</param>
        ''' <param name="dialogTitle">Title of device slection dialog.</param>
        ''' <param name="submitButtonText">Text of submit button of device slection dialog.</param>
        ''' <returns>Boolean indicating to do import or not. </returns>
        ''' <exception cref="ArgumentNullException">
        ''' The required parameter is null or empty.
        ''' </exception>
        ''' <exception cref="PictureAcquisitionException">
        ''' Call to native API has raised an error.
        ''' </exception>
        Public Function ShowDeviceSelectionDialog(ByVal handle As IntPtr, ByVal devicesTypesToShow As DeviceFlag, ByVal dialogTitle As String, ByVal submitButtonText As String) As Boolean
            ' Create the device selection dialog object.
            Dim dialogObject As PictureAcquisitionNative.PhotoAcquireDeviceSelectionDialog = Nothing
            Dim selectDevice As PictureAcquisitionNative.IPhotoAcquireDeviceSelectionDialog = Nothing

            ' Check for null arguments.
            If String.IsNullOrEmpty(dialogTitle) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterDialogTitle)
            ElseIf String.IsNullOrEmpty(submitButtonText) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterSubmitButtonText)
            End If
            ' Set to default value.
            errorResult = APIErrors.S_OK
            Dim deviceType As UInt32
            Dim doImort As Boolean = False
            Dim deviceID As String = String.Empty
            Try
                dialogObject = New PictureAcquisitionNative.PhotoAcquireDeviceSelectionDialog()
                selectDevice = CType(dialogObject, PictureAcquisitionNative.IPhotoAcquireDeviceSelectionDialog)

                ' Set text of submit button of device selection dialog.
                errorResult = CType(selectDevice.SetSubmitButtonText(submitButtonText), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                ' Set title text of device selection dialog.
                errorResult = CType(selectDevice.SetTitle(dialogTitle), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                ' Show device selection dialog and detect only specified devices in the device selection dialog.
                errorResult = CType(selectDevice.DoModal(handle, CType(devicesTypesToShow, UInteger), deviceID, deviceType), APIErrors)
                If errorResult <> APIErrors.S_OK AndAlso errorResult <> APIErrors.E_ABORT Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                Else
                    If errorResult = APIErrors.S_OK Then
                        doImort = True
                        ' Create instance of object, if not already created.
                        If (Me.selectedDeviceInfo Is Nothing) Then
                            Me.selectedDeviceInfo = New DeviceInfo()
                        End If
                        ' Set properties of selectedDeviceInfo object.
                        Me.selectedDeviceInfo.Id = deviceID.ToString()
                        Me.selectedDeviceInfo.Type = CType(deviceType, DeviceType)
                    End If
                End If
            Catch exception As Exception
                Throw New PictureAcquisitionException(exception.Message)
            Finally
                If (Not dialogObject Is Nothing) Then
                    Marshal.ReleaseComObject(dialogObject)
                End If

                If (Not selectDevice Is Nothing) Then
                    Marshal.ReleaseComObject(selectDevice)
                End If
            End Try
            Return doImort
        End Function
#End Region
#Region "OutputFileNameTemplate"
        ''' <summary>
        ''' Sets template that specifies the format of file names.
        ''' </summary>
        ''' <param name="fileNameTemplate">Format of file names.</param>
        ''' <exception cref="ArgumentNullException">
        ''' The required parameter is null or empty.
        ''' </exception>
        ''' <exception cref="ArgumentException">
        ''' The specified parameter is not valid.
        ''' </exception>
        Public Sub SetOutputFilenameTemplate(ByVal fileNameTemplate As String)
            ' Check for null argument.
            If String.IsNullOrEmpty(fileNameTemplate) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterFileNameTemplate)
            End If
            ' Check for maximum length of fileNameTemplate.
            If fileNameTemplate.Length > 207 Then
                Throw New ArgumentException(PictureAcquisitionResource.TemplateMaxLength)
            End If
            Me.fileNameTemplate = fileNameTemplate
        End Sub
        ''' <summary>
        ''' Retrieves file name template.
        ''' </summary>
        ''' <returns>File name template.</returns>
        Public Function GetOutputFilenameTemplate() As String
            Return Me.fileNameTemplate
        End Function
#End Region
#Region "AcquisitionTime"
        ''' <summary>
        ''' Sets the acquisition time of the current session. 
        ''' </summary>
        ''' <param name="timeToset">Time to set in acquisition time.</param>
        ''' <exception cref="PictureAcquisitionException">
        ''' Call to native API has raised an error.
        ''' </exception>
        Public Sub SetAcquisitionTime(ByVal timeToset As System.Runtime.InteropServices.ComTypes.FILETIME)
            ' Set to default value.
            errorResult = APIErrors.S_OK

            ' Create the PhotoAcquire object.
            Dim photoAcquireObject As PictureAcquisitionNative.PhotoAcquire = Nothing
            Dim photoAcquire As PictureAcquisitionNative.IPhotoAcquire = Nothing

            Dim photoAcquireSource As PictureAcquisitionNative.IPhotoAcquireSource = Nothing

            acquireSetting = Nothing
            Try

                photoAcquireObject = New PictureAcquisitionNative.PhotoAcquire()
                photoAcquire = CType(photoAcquireObject, PictureAcquisitionNative.IPhotoAcquire)

                ' Create photosource for acquiring items from.
                errorResult = CType(photoAcquire.CreatePhotoSource(selectedDeviceInfo.Id, photoAcquireSource), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If


                ' Get instance of setting object.
                errorResult = CType(photoAcquireSource.GetPhotoAcquireSettings(acquireSetting), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If

                ' Retrieve acquisition time.
                errorResult = CType(acquireSetting.SetAcquisitionTime(timeToset), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
            Catch exception As Exception
                Throw New PictureAcquisitionException(exception.Message)
            Finally

                If (Not photoAcquireObject Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireObject)
                End If

                If (Not photoAcquire Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquire)
                End If

                If (Not photoAcquireSource Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireSource)
                End If

                If (Not acquireSetting Is Nothing) Then
                    Marshal.ReleaseComObject(acquireSetting)
                End If

            End Try
        End Sub
        ''' <summary>
        ''' Retrieves the acquisition time of the current session. 
        ''' </summary>
        ''' <returns>Acquisition time of the current session.</returns>
        ''' <exception cref="PictureAcquisitionException">
        ''' Call to native API has raised an error.
        ''' </exception>
        Public Function GetAcquisitionTime() As System.Runtime.InteropServices.ComTypes.FILETIME
            ' Set to default value.
            errorResult = APIErrors.S_OK
            ' Create the PhotoAcquire object.
            Dim photoAcquireObject As PictureAcquisitionNative.PhotoAcquire = Nothing
            Dim photoAcquire As PictureAcquisitionNative.IPhotoAcquire = Nothing

            Dim photoAcquireSource As PictureAcquisitionNative.IPhotoAcquireSource = Nothing

            Dim time As System.Runtime.InteropServices.ComTypes.FILETIME = New System.Runtime.InteropServices.ComTypes.FILETIME()
            Try
                photoAcquireObject = New PictureAcquisitionNative.PhotoAcquire()
                photoAcquire = CType(photoAcquireObject, PictureAcquisitionNative.IPhotoAcquire)

                ' Create photosource for acquiring items from.
                errorResult = CType(photoAcquire.CreatePhotoSource(selectedDeviceInfo.Id, photoAcquireSource), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If

                ' Get instance of setting object.
                errorResult = CType(photoAcquireSource.GetPhotoAcquireSettings(acquireSetting), APIErrors)

                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If

                ' Retrieve acquisition time.
                errorResult = CType(acquireSetting.GetAcquisitionTime(time), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
            Catch exception As Exception
                Throw New PictureAcquisitionException(exception.Message)
            Finally

                If (Not photoAcquireObject Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireObject)
                End If

                If (Not photoAcquire Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquire)
                End If

                If (Not photoAcquireSource Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireSource)
                End If

                If (Not acquireSetting Is Nothing) Then
                    Marshal.ReleaseComObject(acquireSetting)
                End If

            End Try
            Return time
        End Function
#End Region

#Region "GetImage"

        ''' <summary>
        ''' Gets Image of all images inside specified device.
        ''' </summary>
        ''' <param name="deviceId">Id of Device, from which to get images.</param>
        ''' <returns>List of image objects of images from specifeid device.</returns>
        ''' <exception cref="ArgumentNullException">
        ''' The required parameter is null or empty.
        ''' </exception>
        ''' <exception cref="PictureAcquisitionException">
        ''' Call to native API has raised an error.
        ''' </exception>
        ''' <remarks>Consecutive call to this or any of these methods :
        ''' GetImage,GetThumbnail and WpfGetThumbnail causes error of 
        ''' "file being used by another process."</remarks>
        Public Function WpfGetImages(ByVal deviceId As String) As List(Of Windows.Controls.Image)

            If (String.IsNullOrEmpty(deviceId)) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterDeviceId)
            End If

            Dim imageList As List(Of Windows.Controls.Image) = New List(Of Windows.Controls.Image)

            ' Create temporary files.
            Dim imageNameList As List(Of String) = Me.CreateTemporaryFiles(deviceId)
            Dim index As Integer

            ' Create temporary files.
            For index = 0 To imageNameList.Count - 1 Step 1

                ' Create bitmapsource of newly created file.
                Dim source As BitmapSource = BitmapFrame.Create(New Uri(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + PictureAcquisitionResource.TempLocation + imageNameList(index)))

                imageList.Add(New Windows.Controls.Image())

                ' Assign bitmapsource to source of Image.
                imageList(index).Source = source

            Next
            Return imageList
        End Function

        ''' <summary>
        ''' Gets Image of all images inside specified device.
        ''' </summary>
        ''' <param name="deviceId">Id of Device, from which to get images.</param>
        ''' <returns>List of image objects of images from specifeid device.</returns>
        ''' <exception cref="ArgumentNullException">
        ''' The required parameter is null or empty.
        ''' </exception>
        ''' <exception cref="PictureAcquisitionException">
        ''' Call to native API has raised an error.
        ''' </exception>
        ''' <remarks>Consecutive call to this or any of these methods :
        ''' WpfGetImage,GetThumbnail and WpfGetThumbnail causes error of 
        ''' "file being used by another process."</remarks>
        Public Function GetImages(ByVal deviceId As String) As List(Of System.Drawing.Image)

            If (String.IsNullOrEmpty(deviceId)) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterDeviceId)
            End If

            Dim imageList As List(Of System.Drawing.Image) = New List(Of System.Drawing.Image)

            Dim index As Integer
            ' Create temporary files.
            Dim imageNameList As List(Of String) = Me.CreateTemporaryFiles(deviceId)
            For index = 0 To imageNameList.Count - 1 Step 1

                ' Create bitmapsource of newly created file.
                Dim source As System.Drawing.Bitmap = New System.Drawing.Bitmap(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + PictureAcquisitionResource.TempLocation + imageNameList(index))
                imageList.Add(CType(source, System.Drawing.Image))
                imageList(index).Tag = imageNameList(index)
            Next
            Return imageList
        End Function

#End Region

#Region "GetThumbnail"

        ''' <summary>
        ''' Gets Image of all images inside specified device.
        ''' </summary>
        ''' <param name="deviceId">Id of Device, from which to get images.</param>
        ''' <returns>List of image objects of images from specifeid device.</returns>
        ''' <exception cref="ArgumentNullException">
        ''' The required parameter is null or empty.
        ''' </exception>
        ''' <exception cref="PictureAcquisitionException">
        ''' Call to native API has raised an error.
        ''' </exception>
        ''' <remarks>Consecutive call to this or any of these methods :
        ''' WpfGetImage,GetImage and WpfGetThumbnail causes error of 
        ''' "file being used by another process."</remarks>
        Public Function GetThumbnails(ByVal deviceId As String) As List(Of System.Drawing.Image)

            ' Get list of images.
            Dim imageList As List(Of System.Drawing.Image) = Me.GetImages(deviceId)

            Dim thumbnailList As List(Of System.Drawing.Image) = New List(Of System.Drawing.Image)

            Dim imgCallBack As System.Drawing.Image.GetThumbnailImageAbort = New System.Drawing.Image.GetThumbnailImageAbort(AddressOf CallBackMethod)

            'Get thumbnails.
            Dim index As Integer
            For index = 0 To imageList.Count - 1 Step 1

                thumbnailList.Add(imageList(index).GetThumbnailImage(100, 100, imgCallBack, IntPtr.Zero))
                thumbnailList(index).Tag = imageList(index).Tag
            Next

            imageList.Clear()

            Return thumbnailList
        End Function

        ''' <summary>
        ''' Gets Image of all images inside specified device.
        ''' </summary>
        ''' <param name="deviceId">Id of Device, from which to get images.</param>
        ''' <returns>List of image objects of images from specifeid device.</returns>
        ''' <exception cref="ArgumentNullException">
        ''' The required parameter is null or empty.
        ''' </exception>
        ''' <exception cref="PictureAcquisitionException">
        ''' Call to native API has raised an error.
        ''' </exception>
        ''' <remarks>Consecutive call to this or any of these methods :
        ''' WpfGetImage,GetThumbnail and WpfGetThumbnail causes error of 
        ''' "file being used by another process."</remarks>
        Public Function WpfGetThumbnails(ByVal deviceId As String) As List(Of Windows.Controls.Image)

            ' Get list of images.
            Dim imageList As List(Of Windows.Controls.Image) = Me.WpfGetImages(deviceId)

            Dim index As Integer

            'Resize images to get thumbnails.
            For index = 0 To imageList.Count - 1 Step 1
                imageList(index).Width = 100
                imageList(index).Height = 100
            Next

            Return imageList
        End Function

#End Region

        ''' <summary>
        ''' Deletes specified item from specified device.
        ''' </summary>
        ''' <param name="itemName">Name of item to be deleted.</param>
        ''' <param name="deviceId">Id of device from which specified delete will be deleted.</param>
        ''' <exception cref="ArgumentNullException">
        ''' The required parameter is null or empty.
        ''' </exception>
        ''' <exception cref="ArgumentException">
        ''' The specified parameter is not valid.
        ''' </exception>
        ''' <exception cref="PictureAcquisitionException">
        ''' Call to native API has raised an error.
        ''' </exception>
        Public Sub DeleteItem(ByVal itemName As String, ByVal deviceId As String)
            ' Create the PhotoAcquire object.
            Dim photoAcquireObject As PictureAcquisitionNative.PhotoAcquire = Nothing
            Dim photoAcquire As PictureAcquisitionNative.IPhotoAcquire = Nothing

            Dim photoAcquireSource As PictureAcquisitionNative.IPhotoAcquireSource = Nothing

            photoAcquireItem = Nothing

            ' Check for null arguments.
            If String.IsNullOrEmpty(itemName) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterItemName)
            End If
            If String.IsNullOrEmpty(deviceId) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterDeviceId)
            End If
            Dim itemList As List(Of String) = Me.GetDeviceItems(deviceId)
            If Not (itemList.Contains(itemName)) Then
                Throw New ArgumentException(PictureAcquisitionResource.ItemNotFound)
            End If
            ' Set to default value.
            errorResult = APIErrors.S_OK
            Try
                photoAcquireObject = New PictureAcquisitionNative.PhotoAcquire()
                photoAcquire = CType(photoAcquireObject, PictureAcquisitionNative.IPhotoAcquire)

                ' Create photosource for acquiring items from.
                errorResult = CType(photoAcquire.CreatePhotoSource(deviceId, photoAcquireSource), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                Dim itemCount As UInt32 = 0
                ' Initialize list of items in speciefied device.
                errorResult = CType(photoAcquireSource.InitializeItemList(True, Nothing, itemCount), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                Dim deviceItemName As String = String.Empty
                Dim canDelete As Boolean = False
                For index As Integer = 0 To CType((itemCount - 1), Integer)
                    ' Serach for item to be deleted in the list of items.
                    ' Retrieve item from specified index.
                    errorResult = CType(photoAcquireSource.GetItemAt(CType(index, UInt32), photoAcquireItem), APIErrors)
                    If errorResult <> APIErrors.S_OK Then
                        Throw New PictureAcquisitionException(errorResult.ToString())
                    End If
                    ' Retrieve name of item.
                    errorResult = CType(photoAcquireItem.GetItemName(deviceItemName), APIErrors)
                    If errorResult <> APIErrors.S_OK Then
                        Throw New PictureAcquisitionException(errorResult.ToString())
                    End If
                    If itemName = deviceItemName Then
                        ' Check whether item can be deleted from device or not.
                        errorResult = CType(photoAcquireItem.CanDelete(canDelete), APIErrors)
                        If canDelete AndAlso (errorResult = APIErrors.S_OK) Then
                            ' Delete specified item from device.
                            errorResult = CType(photoAcquireItem.Delete(), APIErrors)
                            If errorResult <> APIErrors.S_OK Then
                                Throw New PictureAcquisitionException(errorResult.ToString())
                            End If
                            Exit For
                        End If
                    End If
                Next
            Catch exception As Exception
                If exception.Message = PictureAcquisitionResource.ResultFileNotFound Then
                    Throw New ArgumentException(PictureAcquisitionResource.InvalidDeviceId)
                Else
                    Throw New PictureAcquisitionException(exception.Message)
                End If
            Finally

                If (Not photoAcquireObject Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireObject)
                End If

                If (Not photoAcquire Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquire)
                End If

                If (Not photoAcquireSource Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireSource)
                End If

                If (Not photoAcquireItem Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireItem)
                End If

            End Try
        End Sub

        ''' <summary>
        ''' Retrieves list of picture and vedio items from specified device.
        ''' </summary>
        ''' <param name="deviceId">Id of device from which list of items is to be retrieved.</param>
        ''' <returns>List of picture and video items of specified device.</returns>
        ''' <exception cref="ArgumentNullException">
        ''' The required parameter is null or empty.
        ''' </exception>
        ''' <exception cref="ArgumentException">
        ''' The specified parameter is not valid.
        ''' </exception>
        ''' <exception cref="PictureAcquisitionException">
        ''' Call to native API has raised an error.
        ''' </exception>
        Public Function GetDeviceItems(ByVal deviceId As String) As List(Of String)

            ' Create the PhotoAcquire object.
            Dim photoAcquireObject As PictureAcquisitionNative.PhotoAcquire = Nothing
            Dim photoAcquire As PictureAcquisitionNative.IPhotoAcquire = Nothing

            Dim photoAcquireSource As PictureAcquisitionNative.IPhotoAcquireSource = Nothing

            photoAcquireItem = Nothing

            ' Check for null arguments.
            If String.IsNullOrEmpty(deviceId) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterDeviceId)
            End If
            ' Set to default value.
            errorResult = APIErrors.S_OK
            Dim itemList As List(Of String)
            Try
                photoAcquireObject = New PictureAcquisitionNative.PhotoAcquire()
                photoAcquire = CType(photoAcquireObject, PictureAcquisitionNative.IPhotoAcquire)

                ' Create photosource for acquiring items from.
                errorResult = CType(photoAcquire.CreatePhotoSource(deviceId, photoAcquireSource), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                Dim itemCount As UInt32 = 0
                ' Initialize list of items in speciefied device.
                errorResult = CType(photoAcquireSource.InitializeItemList(True, Nothing, itemCount), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                ' Create list of length equal to total items in the specified device.
                itemList = New List(Of String)(CType(itemCount, Integer))
                Dim itemName As String = String.Empty
                For index As Integer = 0 To CType((itemCount - 1), Integer)
                    ' Add item names in the list of items.
                    ' Retrieve item from specified index.
                    errorResult = CType(photoAcquireSource.GetItemAt(CType(index, UInt32), photoAcquireItem), APIErrors)
                    If errorResult <> APIErrors.S_OK Then
                        Throw New PictureAcquisitionException(errorResult.ToString())
                    End If
                    ' Retrieve name of item.
                    errorResult = CType(photoAcquireItem.GetItemName(itemName), APIErrors)
                    If errorResult <> APIErrors.S_OK Then
                        Throw New PictureAcquisitionException(errorResult.ToString())
                    End If
                    itemList.Add(itemName)
                Next
            Catch exception As Exception
                If exception.Message = PictureAcquisitionResource.ResultFileNotFound Then
                    Throw New ArgumentException(PictureAcquisitionResource.InvalidDeviceId)
                Else
                    Throw New PictureAcquisitionException(exception.Message)
                End If
            Finally

                If (Not photoAcquireObject Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireObject)
                End If

                If (Not photoAcquire Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquire)
                End If

                If (Not photoAcquireSource Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireSource)
                End If

                If (Not photoAcquireItem Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireItem)
                End If

            End Try
            Return itemList
        End Function

        ''' <summary>
        ''' Get the selected device details.
        ''' </summary>
        ''' <returns>Object of DeviceInfo class containing information of selected device.</returns>
        ''' <exception cref="PictureAcquisitionException">
        ''' Call to native API has raised an error.
        ''' </exception>
        Public Function GetSelectedDevice() As DeviceInfo

            ' Create the PhotoAcquire object.
            Dim photoAcquireObject As PictureAcquisitionNative.PhotoAcquire = Nothing
            Dim photoAcquire As PictureAcquisitionNative.IPhotoAcquire = Nothing

            Dim photoAcquireSource As PictureAcquisitionNative.IPhotoAcquireSource = Nothing

            ' Set to default value.
            errorResult = APIErrors.S_OK
            Dim deviceFriendlyName As String = String.Empty
            Try

                If selectedDeviceInfo IsNot Nothing Then

                    photoAcquireObject = New PictureAcquisitionNative.PhotoAcquire()
                    photoAcquire = CType(photoAcquireObject, PictureAcquisitionNative.IPhotoAcquire)

                    ' Create photosource for acquiring items from.
                    errorResult = CType(photoAcquire.CreatePhotoSource(selectedDeviceInfo.Id, photoAcquireSource), APIErrors)
                    If errorResult <> APIErrors.S_OK Then
                        Throw New PictureAcquisitionException(errorResult.ToString())
                    End If
                    ' Get friendly name of selected device.
                    errorResult = CType(photoAcquireSource.GetFriendlyName(deviceFriendlyName), APIErrors)
                    If errorResult <> APIErrors.S_OK Then
                        Throw New PictureAcquisitionException(errorResult.ToString())
                    End If
                    ' Set friendly name of selcted device to the object property.
                    selectedDeviceInfo.FriendlyName = deviceFriendlyName
                Else
                    Throw New PictureAcquisitionException(PictureAcquisitionResource.DeviceNotSelected)
                End If
            Catch exception As Exception
                Throw New PictureAcquisitionException(exception.Message)
            Finally

                If (Not photoAcquireObject Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireObject)
                End If

                If (Not photoAcquire Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquire)
                End If

                If (Not photoAcquireSource Is Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireSource)
                End If

            End Try
            Return selectedDeviceInfo
        End Function

        ''' <summary>
        ''' Shows dialog for doing import setting for various devices.
        ''' </summary>
        ''' <exception cref="PictureAcquisitionException">
        ''' Call to native API has raised an error.
        ''' </exception>
        Public Sub ShowImportSettings()
            ' Set to default value.
            errorResult = APIErrors.S_OK
            Dim optionDialogObject As PictureAcquisitionNative.PhotoAcquireOptionsDialog = Nothing
            Dim optionDialog As PictureAcquisitionNative.IPhotoAcquireOptionsDialog = Nothing

            Try

                ' Create the object of settings dialog.
                optionDialogObject = New PictureAcquisitionNative.PhotoAcquireOptionsDialog()
                optionDialog = DirectCast(optionDialogObject, PictureAcquisitionNative.IPhotoAcquireOptionsDialog)
                ' Initialize import settings from registry.
                errorResult = CType(optionDialog.Initialize(Nothing), APIErrors)
                If errorResult <> APIErrors.S_OK Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                Dim settingResult As Int32 = 0
                ' Show import settings dialog.
                errorResult = CType(optionDialog.DoModal(IntPtr.Zero, settingResult), APIErrors)

                If (errorResult <> APIErrors.S_OK And (errorResult <> APIErrors.S_FALSE)) Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If

                ' If the user clicked OK, then save the updated settings.
                If settingResult = 1 Then
                    optionDialog.SaveData()
                End If
            Catch exception As Exception
                Throw New PictureAcquisitionException(exception.Message)
            Finally
                If (Not optionDialogObject Is Nothing) Then
                    Marshal.ReleaseComObject(optionDialogObject)
                End If
                If (Not optionDialog Is Nothing) Then
                    Marshal.ReleaseComObject(optionDialog)
                End If
            End Try
        End Sub


        ''' <summary>
        ''' Gets Image of all images inside specified device.
        ''' </summary>
        ''' <param name="deviceId">Id of Device, from which to get images.</param>
        ''' <returns>List of image objects of images from specifeid device.</returns>
        ''' <exception cref="ArgumentNullException">
        ''' The required parameter is null or empty.
        ''' </exception>
        ''' <exception cref="PictureAcquisitionException">
        ''' Call to native API has raised an error.
        ''' </exception>
        Public Function GetPictureImage(ByVal deviceId As String) As List(Of Windows.Controls.Image)
            ' Check for null arguments.
            If (String.IsNullOrEmpty(deviceId)) Then
                Throw New ArgumentNullException(PictureAcquisitionResource.ParameterDeviceId)
            End If

            ' Create the PhotoAcquire object.
            Dim photoAcquireObject As PictureAcquisitionNative.PhotoAcquire = Nothing
            Dim photoAcquire As PictureAcquisitionNative.IPhotoAcquire = Nothing

            Dim photoAcquireSource As PictureAcquisitionNative.IPhotoAcquireSource = Nothing

            ' Set to default value.        
            errorResult = APIErrors.S_OK

            Dim itemsImportedList As List(Of String) = New List(Of String)

            Dim imageList As List(Of Windows.Controls.Image) = New List(Of Windows.Controls.Image)

            Try

                photoAcquireObject = New PictureAcquisitionNative.PhotoAcquire()
                photoAcquire = CType(photoAcquireObject, PictureAcquisitionNative.IPhotoAcquire)

                errorResult = CType(photoAcquire.CreatePhotoSource(deviceId, photoAcquireSource), APIErrors)

                If (errorResult <> APIErrors.S_OK) Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If

                Dim itemCount As UInt32 = 0
                errorResult = CType(photoAcquireSource.InitializeItemList(True, IntPtr.Zero, itemCount), APIErrors)

                If (errorResult <> APIErrors.S_OK) Then
                    Throw New PictureAcquisitionException(errorResult.ToString())
                End If
                Dim index As Integer
                For index = 0 To CType(itemCount - 1, Integer) Step 1

                    Dim comStream As System.Runtime.InteropServices.ComTypes.IStream = Nothing
                    errorResult = CType(photoAcquireSource.GetItemAt(CType(index, UInt32), photoAcquireItem), APIErrors)

                    If (errorResult <> APIErrors.S_OK) Then
                        Throw New PictureAcquisitionException(errorResult.ToString())
                    End If

                    ' Get object of stream.
                    errorResult = CType(photoAcquireItem.GetStream(comStream), APIErrors)

                    If (errorResult <> APIErrors.S_OK) Then
                        Throw New PictureAcquisitionException(errorResult.ToString())
                    End If

                    Dim comStreamInfo As System.Runtime.InteropServices.ComTypes.STATSTG = New System.Runtime.InteropServices.ComTypes.STATSTG()

                    ' Get information about retrieved stream object.
                    comStream.Stat(comStreamInfo, 0)

                    Dim bytes(CType(comStreamInfo.cbSize, Integer)) As Byte

                    ' Read all bytes of stream in byte buffer.
                    comStream.Read(bytes, CType(comStreamInfo.cbSize, Integer), IntPtr.Zero)

                    If (Not (Directory.Exists(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + PictureAcquisitionResource.TempLocation))) Then
                        Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + PictureAcquisitionResource.TempLocation)
                    End If

                    ' Create a new file steram (file) at specified target location.
                    Dim FileStream As FileStream = New FileStream(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + PictureAcquisitionResource.TempLocation + comStreamInfo.pwcsName, FileMode.Create)

                    ' Write bytes of buffer in this new file.
                    FileStream.Write(bytes, 0, CType(comStreamInfo.cbSize, Integer))

                    FileStream.Close()

                    ' Create bitmapsource of newly created file.
                    Dim source As BitmapSource = BitmapFrame.Create(New Uri(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + PictureAcquisitionResource.TempLocation + comStreamInfo.pwcsName))

                    FileStream.Dispose()

                    FileStream = Nothing

                    imageList.Add(New Windows.Controls.Image())

                    ' Assign bitmapsource to source of Image.
                    imageList(index).Source = source

                    imageList(index).Height = 100
                    imageList(index).Width = 100

                    If (comStream IsNot Nothing) Then
                        Marshal.ReleaseComObject(comStream)
                    End If
                Next
            Catch exception As Exception

                If (exception.Message = PictureAcquisitionResource.ResultFileNotFound) Then
                    Throw New ArgumentException(PictureAcquisitionResource.InvalidDeviceId)
                ElseIf (exception.Message = PictureAcquisitionResource.InvalidArg) Then
                    Throw New ArgumentException(PictureAcquisitionResource.InvalidDeviceId)
                Else
                    Throw New PictureAcquisitionException(exception.Message)
                End If
            Finally

                If (photoAcquireObject IsNot Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireObject)
                End If

                If (photoAcquire IsNot Nothing) Then
                    Marshal.ReleaseComObject(photoAcquire)
                End If

                If (photoAcquireSource IsNot Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireSource)
                End If

                If (photoAcquireItem IsNot Nothing) Then
                    Marshal.ReleaseComObject(photoAcquireItem)
                End If
            End Try
            Return imageList
        End Function
#End Region
    End Class
#Region "Public classes"
    ''' <summary>
    ''' Provides information about device.
    ''' </summary>
    Public Class DeviceInfo
#Region "Private members"
        ''' <summary>
        ''' Friendly name of device.
        ''' </summary>
        Private m_friendlyName As String
        ''' <summary>
        ''' Id of device.
        ''' </summary>
        Private m_id As String
        ''' <summary>
        ''' Type of device.
        ''' </summary>
        Private m_type As DeviceType
#End Region
#Region "Public properties"
        ''' <summary>
        ''' Friendly name of device.
        ''' </summary>
        Public Property FriendlyName() As String
            Get
                Return m_friendlyName
            End Get
            Set(ByVal value As String)
                m_friendlyName = value
            End Set
        End Property
        ''' <summary>
        ''' Id of device.
        ''' </summary>
        Public Property Id() As String
            Get
                Return m_id
            End Get
            Set(ByVal value As String)
                m_id = value
            End Set
        End Property
        ''' <summary>
        ''' Type of device.
        ''' </summary>
        Public Property Type() As DeviceType
            Get
                Return m_type
            End Get
            Set(ByVal value As DeviceType)
                m_type = value
            End Set
        End Property
#End Region
    End Class
#End Region
#Region "Enumerations"
    ''' <summary>
    ''' Specifies different types of device.
    ''' </summary>
    Public Enum DeviceType
        ''' <summary>
        ''' Specifies that the type of the selected device is unknown.
        ''' </summary>
        Unknown = 0
        ''' <summary>
        ''' Specifies that the type of the selected device is Windows Portable Devices (WPD).
        ''' </summary>
        Wpd = 1
        ''' <summary>
        ''' Specifies that the type of the selected device is Windows Image Acquisition (WIA).
        ''' </summary>
        Wia = 2
        ''' <summary>
        ''' Specifies that the type of the selected device is Still Image Architecture (STI).
        ''' </summary>
        Sti = 3
        ''' <summary>
        ''' Not supported.
        ''' </summary>
        Twain = 4
        ''' <summary>
        ''' Specifies that the selected device is a removable drive in the file system.
        ''' </summary>
        FS = 5
    End Enum
    ''' <summary>
    ''' Specifies different flags for device detection in device slection dialog.
    ''' </summary>
    Public Enum DeviceFlag
        ''' <summary>
        ''' None.
        ''' </summary>
        None = 0
        ''' <summary>
        ''' Specifies devices of type Windows Portable Devices (WPD).
        ''' </summary>
        Wpd = 1
        ''' <summary>
        ''' Specifies cameras of type Windows Image Acquisition (WIA).
        ''' </summary>
        Cameras = 2
        ''' <summary>
        ''' Specifies scanners of type Windows Image Acquisition (WIA).
        ''' </summary>
        Scanners = 4
        ''' <summary>
        ''' Specifies devices of type Still Image Architecture (STI).
        ''' </summary>
        Sti = 8
        ''' <summary>
        ''' Specifies removable storage devices, such as CD drives or Pan drive.
        ''' </summary>
        FS = 32
        ''' <summary>
        ''' Specifies removable storage devices, such as CD drives or card readers.
        ''' </summary>
        CardReaders = 32
        ''' <summary>
        ''' Specifies digital video camera devices.
        ''' </summary>
        DigitalVideoCameras = 64
        ''' <summary>
        ''' Specifies all devices.
        ''' </summary>
        All = 65535
        ''' <summary>
        ''' Specifies devices that are offline.  Not supported by all device types.
        ''' </summary>
        OffLine = 131072
    End Enum
    Friend Enum APIErrors As Integer
        ''' <summary>
        ''' Invalid argument.
        ''' </summary>
        E_INVALIDARG = &H80070057
        ''' <summary>
        ''' The system cannot find the file specified
        ''' </summary>
        FILE_NOT_FOUND = &H80070002
        ''' <summary>
        ''' The operation completed successfully.
        ''' </summary>
        S_OK = &H0
        ''' <summary>
        ''' Incorrect function.
        ''' </summary>
        S_FALSE = &H1
        ''' <summary>
        ''' Operation aborted.
        ''' </summary>
        E_ABORT = &H80004004
        ''' <summary>
        ''' Unspecified error. 
        ''' </summary>
        E_FAIL = &H80004005
        ''' <summary>
        ''' Interface not supported. 
        ''' </summary>
        E_NOINTERFACE = &H80004002
        ''' <summary>
        ''' Not implemented. 
        ''' </summary>
        E_NOTIMPL = &H80004001
        ''' <summary>
        ''' Invalid pointer. 
        ''' </summary>
        E_POINTER = &H80004003
        ''' <summary>
        ''' Catastrophic failure. 
        ''' </summary>
        E_UNEXPECTED = &H8000FFFF
    End Enum
#End Region
End Namespace
